﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;

namespace CMSClient
{
    public class Client
    {
        private System.Text.Encoding encode=Encoding.GetEncoding("gb2312");
        
        public string GetClientBySocket(string UrlString, System.Text.Encoding encode)
        {
            this.encode = encode;
            return GetClientBySocket(UrlString);
        }
       

        public string GetClientBySocket(string UrlString)
        {
            string host;
            int port = 80;
            //System.Web.HttpContext.Current.Response.Write(UrlString);
            //System.Web.HttpContext.Current.Response.End();
            if (UrlString.StartsWith("http://"))
            {
                string temp = UrlString.Trim();
                temp = temp.Substring(7, temp.Length - 7);
                if (temp.IndexOf("/") == -1)
                {
                    host = temp;
                }
                else
                {
                    host = temp.Substring(0, temp.IndexOf("/"));
                }
                int portIndex=host.IndexOf(":");
                if ( portIndex!= -1)
                {
                    port = int.Parse(host.Substring(portIndex+1));
                    host = host.Substring(0, portIndex);
                }
            }
            else
            {
                host = UrlString.Substring(0, UrlString.IndexOf("/"));
            }

            IPAddress[] ips = Dns.GetHostAddresses(host);
            IPAddress ip = ips[0];
            IPEndPoint serverhost = new IPEndPoint(ip, port);
            Socket clientSocket=null;
            try
            {
                clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                clientSocket.Connect(serverhost);

                string httpReq = "GET " + UrlString + " HTTP/1.1\r\n";
                httpReq += "Host:"+host+"\r\n";
                httpReq += "Connection: close\r\n\r\n";
                StringBuilder txtHTML = new StringBuilder();
           
                clientSocket.Send(encode.GetBytes(httpReq));
                Byte[] buffer = new byte[10240];
                int byteCount = clientSocket.Receive(buffer, buffer.Length, 0);
                List<byte> bLst = new List<byte>();
                AddByte(bLst, buffer, byteCount);
                while (byteCount > 0)
                {
                    byteCount = clientSocket.Receive(buffer, buffer.Length, 0);
                    AddByte(bLst, buffer, byteCount);
                 
                }
                byte[] bbs = new byte[bLst.Count];
                for (int i = 0; i < bLst.Count;i++ )
                {
                    bbs[i] = bLst[i];
                }
               
                var str =  encode.GetString(bbs, 0, bbs.Length);
                //判断页面状态
                string strState = str.Substring(0, str.IndexOf("\r\n"));
                var ss = strState.Substring(strState.IndexOf(' ')+1);
                if (ss!="200 OK")
                {
                    throw new Exception(ss);
                }

                str = str.Substring(str.IndexOf("\r\n\r\n")+4);
                
                return str;
            }
            catch (Exception err)
            {
                throw err;
            }
            finally
            {
                if (clientSocket != null)
                {
                    try
                    {
                        clientSocket.Close();
                    }
                    catch
                    {
                    }
                }
            }
        }

        public byte[] GetData(string UrlString)
        {
            string host;
            int port = 80;
            if (UrlString.StartsWith("http://"))
            {
                string temp = UrlString.Trim();
                temp = temp.Substring(7, temp.Length - 7);
                if (temp.IndexOf("/") == -1)
                {
                    host = temp;
                }
                else
                {
                    host = temp.Substring(0, temp.IndexOf("/"));
                }
                int portIndex = host.IndexOf(":");
                if (portIndex != -1)
                {
                    port = int.Parse(host.Substring(portIndex + 1));
                    host = host.Substring(0, portIndex);
                }
            }
            else
            {
                host = UrlString.Substring(0, UrlString.IndexOf("/"));
            }

            IPAddress[] ips = Dns.GetHostAddresses(host);
            IPAddress ip = ips[0];
            IPEndPoint serverhost = new IPEndPoint(ip, port);
            Socket clientSocket = null;
            try
            {
                clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                clientSocket.Connect(serverhost);

                string httpReq = "GET " + UrlString + " HTTP/1.1\r\n";
                httpReq += "Host:" + host + "\r\n";
                httpReq += "Connection: close\r\n\r\n";
                StringBuilder txtHTML = new StringBuilder();

                clientSocket.Send(encode.GetBytes(httpReq));
                Byte[] buffer = new byte[10240];
                int byteCount = clientSocket.Receive(buffer, buffer.Length, 0);
                List<byte> bLst = new List<byte>();
                AddByte(bLst, buffer, byteCount);
                while (byteCount > 0)
                {
                    byteCount = clientSocket.Receive(buffer, buffer.Length, 0);
                    AddByte(bLst, buffer, byteCount);

                }
                byte[] bbs = new byte[bLst.Count];
                for (int i = 0; i < bLst.Count; i++)
                {
                    bbs[i] = bLst[i];
                }

                var str = encode.GetString(bbs, 0, bbs.Length);
                //判断页面状态
                string strState = string.Empty;
                for (int i = 0; i < bbs.Length; i++)
                {
                    if (bbs[i] == '\r' && bbs[i + 1] == '\n')
                    {
                        strState = this.encode.GetString(bbs, 0, i);
                        break;
                    }
                }
                var ss = strState.Substring(strState.IndexOf(' ') + 1);
                if (ss != "200 OK")
                {
                    throw new Exception(ss);
                }
                int dataIndex = 0;
                for (int i = 0; i < bbs.Length; i++)
                {
                    if (bbs[i] == '\r' && bbs[i + 1] == '\n' && bbs[i + 2] == '\r' && bbs[i + 3] == '\n')
                    {
                        dataIndex = i + 4;
                        break;
                    }
                }
                byte [] data=new byte[bbs.Length-dataIndex];
                for (int i = dataIndex,j=0; i < bbs.Length; i++,j++)
                {
                    data[j] = bbs[i];
                }
                return data;
            }
            catch (Exception err)
            {
                throw err;
            }
            finally
            {
                if (clientSocket != null)
                {
                    try
                    {
                        clientSocket.Close();
                    }
                    catch
                    {
                    }
                }
            }
        }

        void AddByte(List<byte> lst, byte[] data, int count)
        {
            for (int i = 0; i < count; i++)
            {
                lst.Add(data[i]);
            }
        }

        public static void Main()
        {
            Client c = new Client();
            //byte[] p = c.GetData("http://172.28.1.91/?id=000001&t=8&p=2&i=vol&w=250&h=120&c=16");
            byte[] p = c.GetData("http://www.emoney.cn");
            File.Create("c:\\100.html").Write(p, 0, p.Length);
        }
    }
}
